home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / uucp-104.lha / uucp-1.04 / uuconv.c < prev    next >
C/C++ Source or Header  |  1993-02-13  |  55KB  |  2,013 lines

  1. /* uuconv.c
  2.    Convert one type of UUCP configuration file to another.
  3.  
  4.    Copyright (C) 1991, 1992 Ian Lance Taylor
  5.  
  6.    This file is part of the Taylor UUCP package.
  7.  
  8.    This program is free software; you can redistribute it and/or
  9.    modify it under the terms of the GNU General Public License as
  10.    published by the Free Software Foundation; either version 2 of the
  11.    License, or (at your option) any later version.
  12.  
  13.    This program is distributed in the hope that it will be useful, but
  14.    WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.    General Public License for more details.
  17.  
  18.    You should have received a copy of the GNU General Public License
  19.    along with this program; if not, write to the Free Software
  20.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22.    The author of the program may be contacted at ian@airs.com or
  23.    c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
  24.    */
  25.  
  26. #include "uucnfi.h"
  27.  
  28. #if USE_RCS_ID
  29. const char uuconv_rcsid[] = "$Id: uuconv.c,v 1.11 1992/12/30 05:07:59 ian Rel $";
  30. #endif
  31.  
  32. #include "getopt.h"
  33.  
  34. /* Local functions.  */
  35.  
  36. static void uvusage P((void));
  37. static void uvwrite_time P((FILE *e, struct uuconf_timespan *qtime));
  38. static void uvwrite_string P((FILE *e, const char *zarg, const char *zcmd));
  39. static void uvwrite_size P((FILE *e, struct uuconf_timespan *qsize,
  40.                 const char *zcmd));
  41. static void uvwrite_boolean P((FILE *e, int iarg, const char *zcmd));
  42. static void uvwrite_string_array P((FILE *e, char **pz, const char *zcmd));
  43. static void uvwrite_chat_script P((FILE *e, char **pz));
  44. static void uvwrite_chat P((FILE *e, const struct uuconf_chat *qchat,
  45.                 const struct uuconf_chat *qlast,
  46.                 const char *zprefix, boolean fforce));
  47. static void uvwrite_proto_params P((FILE *e,
  48.                     const struct uuconf_proto_param *qparam,
  49.                     const char *zprefix));
  50. static void uvwrite_taylor_system P((FILE *e,
  51.                      const struct uuconf_system *qsys));
  52. static void uvwrite_v2_system P((FILE *e,
  53.                  const struct uuconf_system *qsys));
  54. static void uvwrite_hdb_system P((FILE *e,
  55.                   const struct uuconf_system *qsys));
  56. static boolean fvperm_string_cmp P((const char *z1, const char *z2));
  57. static boolean fvperm_array_cmp P((const char **pz1, const char **pz2));
  58. static void uvadd_perm P((struct shpermissions *qadd));
  59. static void uvwrite_perms P((void));
  60. static void uvwrite_perm_array P((FILE *e, const char **pz,
  61.                   const char *zcmd, size_t *pccol));
  62. static void uvwrite_perm_boolean P((FILE *e, int f, const char *zcmd,
  63.                     size_t *pccol, boolean fsendfiles));
  64. static void uvwrite_perm_rw_array P((FILE *e, const char **pz,
  65.                      const char *zcmd, size_t *pccol));
  66. static void uvwrite_perm_string P((FILE *e, const char *z, const char *zcmd,
  67.                    size_t *pccol));
  68. static int ivwrite_taylor_port P((struct uuconf_port *qport,
  69.                   pointer pinfo));
  70. static int ivwrite_v2_port P((struct uuconf_port *qport, pointer pinfo));
  71. static int ivwrite_hdb_port P((struct uuconf_port *qport, pointer pinfo));
  72. static void uvwrite_taylor_port P((FILE *e, struct uuconf_port *qport,
  73.                    const char *zprefix));
  74. static void uvwrite_taylor_dialer P((FILE *e, struct uuconf_dialer *qdialer,
  75.                      const char *zprefix));
  76. static void uvwrite_hdb_dialer P((FILE *e, struct uuconf_dialer *qdialer));
  77. static void uvuuconf_error P((pointer puuconf, int iret));
  78.  
  79. /* A list of Permissions entries built when writing out HDB system
  80.    information.  */
  81. static struct shpermissions *qVperms;
  82.  
  83. /* Type of configuration file.  */
  84. enum tconfig
  85. {
  86.   CONFIG_TAYLOR,
  87.   CONFIG_V2,
  88.   CONFIG_HDB
  89. };
  90.  
  91. /* Long getopt options.  */
  92. static const struct option asVlongopts[] = { { NULL, 0, NULL, 0 } };
  93.  
  94. int
  95. main (argc, argv)
  96.      int argc;
  97.      char **argv;
  98. {
  99.   /* -I: The configuration file name.  */
  100.   const char *zconfig = NULL;
  101.   /* -i: Input type.  */
  102.   const char *zinput = NULL;
  103.   /* -o: Output type.  */
  104.   const char *zoutput = NULL;
  105.   /* -p: Program name.  */
  106.   const char *zprogram = NULL;
  107.   int iopt;
  108.   enum tconfig tinput, toutput;
  109.   int iret;
  110.   pointer pinput;
  111.  
  112.   while ((iopt = getopt_long (argc, argv, "i:I:o:p:x:", asVlongopts,
  113.                   (int *) NULL)) != EOF)
  114.     {
  115.       switch (iopt)
  116.     {
  117.     case 'i':
  118.       /* Input type.  */
  119.       zinput = optarg;
  120.       break;
  121.  
  122.     case 'o':
  123.       /* Output type.  */
  124.       zoutput = optarg;
  125.       break;
  126.  
  127.     case 'p':
  128.       /* Program name.  */
  129.       zprogram = optarg;
  130.       break;
  131.  
  132.     case 'I':
  133.       /* Set the configuration file name.  */
  134.       zconfig = optarg;
  135.       break;
  136.  
  137.     case 'x':
  138.       /* Set the debugging level.  */
  139.       break;
  140.  
  141.     case 0:
  142.       /* Long option found and flag set.  */
  143.       break;
  144.  
  145.     default:
  146.       uvusage ();
  147.       break;
  148.     }
  149.     }
  150.  
  151.   if (optind != argc
  152.       || zinput == NULL
  153.       || zoutput == NULL)
  154.     uvusage ();
  155.  
  156.   if (strcasecmp (zinput, "taylor") == 0)
  157.     tinput = CONFIG_TAYLOR;
  158.   else if (strcasecmp (zinput, "v2") == 0)
  159.     tinput = CONFIG_V2;
  160.   else if (strcasecmp (zinput, "hdb") == 0)
  161.     tinput = CONFIG_HDB;
  162.   else
  163.     {
  164.       uvusage ();
  165.       tinput = CONFIG_TAYLOR;
  166.     }
  167.  
  168.   if (strcasecmp (zoutput, "taylor") == 0)
  169.     toutput = CONFIG_TAYLOR;
  170.   else if (strcasecmp (zoutput, "v2") == 0)
  171.     toutput = CONFIG_V2;
  172.   else if (strcasecmp (zoutput, "hdb") == 0)
  173.     toutput = CONFIG_HDB;
  174.   else
  175.     {
  176.       uvusage ();
  177.       toutput = CONFIG_TAYLOR;
  178.     }
  179.  
  180.   if (tinput == toutput)
  181.     uvusage ();
  182.  
  183.   iret = UUCONF_SUCCESS;
  184.  
  185.   /* Initialize the input.  */
  186.   pinput = NULL;
  187.   switch (tinput)
  188.     {
  189.     case CONFIG_TAYLOR:
  190.       iret = uuconf_taylor_init (&pinput, zprogram, zconfig);
  191.       break;
  192.     case CONFIG_V2:
  193.       iret = uuconf_v2_init (&pinput);
  194.       break;
  195.     case CONFIG_HDB:
  196.       iret = uuconf_hdb_init (&pinput, zprogram);
  197.       break;
  198.     }
  199.   if (iret != UUCONF_SUCCESS)
  200.     {
  201.       uvuuconf_error (pinput, iret);
  202.       exit (EXIT_FAILURE);
  203.     }
  204.  
  205.   {
  206.     char **pzsystems;
  207.     char *zsys;
  208.     char abtaylor[sizeof ZCURDIR + sizeof SYSFILE - 1];
  209.     char abv2[sizeof ZCURDIR + sizeof V2_SYSTEMS - 1];
  210.     char abhdb[sizeof ZCURDIR + sizeof HDB_SYSTEMS - 1];
  211.     FILE *esys;
  212.     char **pz;
  213.  
  214.     /* Get the list of systems.  */
  215.     switch (tinput)
  216.       {
  217.       case CONFIG_TAYLOR:
  218.     iret = uuconf_taylor_system_names (pinput, &pzsystems, FALSE);
  219.     break;
  220.       case CONFIG_V2:
  221.     iret = uuconf_v2_system_names (pinput, &pzsystems, FALSE);
  222.     break;
  223.       case CONFIG_HDB:
  224.     iret = uuconf_hdb_system_names (pinput, &pzsystems, FALSE);
  225.     break;
  226.       }
  227.     if (iret != UUCONF_SUCCESS)
  228.       uvuuconf_error (pinput, iret);
  229.     else
  230.       {
  231.     /* Open the sys file for the output type.  */
  232.     switch (toutput)
  233.       {
  234.       default:
  235.       case CONFIG_TAYLOR:
  236.         sprintf (abtaylor, "%s%s", ZCURDIR, SYSFILE);
  237.         zsys = abtaylor;
  238.         break;
  239.       case CONFIG_V2:
  240.         sprintf (abv2, "%s%s", ZCURDIR, V2_SYSTEMS);
  241.         zsys = abv2;
  242.         break;
  243.       case CONFIG_HDB:
  244.         sprintf (abhdb, "%s%s", ZCURDIR, HDB_SYSTEMS);
  245.         zsys = abhdb;
  246.         break;
  247.       }
  248.     esys = fopen (zsys, "w");
  249.     if (esys == NULL)
  250.       {
  251.         fprintf (stderr, "uuchk:%s: ", zsys);
  252.         perror ("fopen");
  253.         exit (EXIT_FAILURE);
  254.       }
  255.  
  256.     fprintf (esys, "# %s file automatically generated by uuconv.\n",
  257.          zsys);
  258.  
  259.     /* Read and write each system.  We cheat and call the internal
  260.        routines, so that we can easily detect default information and
  261.        not write it out.  This isn't necessary, but it makes the output
  262.        smaller and simpler.  */
  263.     for (pz = pzsystems; *pz != NULL; pz++)
  264.       {
  265.         struct uuconf_system ssys;
  266.  
  267.         switch (tinput)
  268.           {
  269.           case CONFIG_TAYLOR:
  270.         iret = _uuconf_itaylor_system_internal (pinput, *pz, &ssys);
  271.         break;
  272.           case CONFIG_V2:
  273.         iret = _uuconf_iv2_system_internal (pinput, *pz, &ssys);
  274.         break;
  275.           case CONFIG_HDB:
  276.         iret = _uuconf_ihdb_system_internal (pinput, *pz, &ssys);
  277.         break;
  278.           }
  279.         if (iret != UUCONF_SUCCESS)
  280.           uvuuconf_error (pinput, iret);
  281.         else
  282.           {
  283.         switch (toutput)
  284.           {
  285.           case CONFIG_TAYLOR:
  286.             uvwrite_taylor_system (esys, &ssys);
  287.             break;
  288.           case CONFIG_V2:
  289.             uvwrite_v2_system (esys, &ssys);
  290.             break;
  291.           case CONFIG_HDB:
  292.             uvwrite_hdb_system (esys, &ssys);
  293.             break;
  294.           }
  295.         if (toutput != CONFIG_HDB)
  296.           (void) uuconf_system_free (pinput, &ssys);
  297.           }
  298.       }
  299.  
  300.     if (toutput == CONFIG_HDB)
  301.       uvwrite_perms ();
  302.  
  303.     if (ferror (esys)
  304.         || fclose (esys) == EOF)
  305.       {
  306.         fprintf (stderr, "uuchk:%s: error during output\n", zsys);
  307.         exit (EXIT_FAILURE);
  308.       }
  309.       }
  310.   }
  311.  
  312.   {
  313.     /* Open the port file for the output type.  */
  314.     char *zport;
  315.     char abtaylor[sizeof ZCURDIR + sizeof PORTFILE - 1];
  316.     char abv2[sizeof ZCURDIR + sizeof V2_DEVICES - 1];
  317.     char abhdb[sizeof ZCURDIR + sizeof HDB_DEVICES - 1];
  318.     FILE *eport;
  319.     int (*piportfn) P((struct uuconf_port *, pointer));
  320.     struct uuconf_port sport;
  321.  
  322.     switch (toutput)
  323.       {
  324.       default:
  325.       case CONFIG_TAYLOR:
  326.     sprintf (abtaylor, "%s%s", ZCURDIR, PORTFILE);
  327.     zport = abtaylor;
  328.     piportfn = ivwrite_taylor_port;
  329.     break;
  330.       case CONFIG_V2:
  331.     sprintf (abv2, "%s%s", ZCURDIR, V2_DEVICES);
  332.     zport = abv2;
  333.     piportfn = ivwrite_v2_port;
  334.     break;
  335.       case CONFIG_HDB:
  336.     sprintf (abhdb, "%s%s", ZCURDIR, HDB_DEVICES);
  337.     zport = abhdb;
  338.     piportfn = ivwrite_hdb_port;
  339.     break;
  340.       }
  341.     eport = fopen (zport, "w");
  342.     if (eport == NULL)
  343.       {
  344.     fprintf (stderr, "uuchk:%s: ", zport);
  345.     perror ("fopen");
  346.     exit (EXIT_FAILURE);
  347.       }
  348.  
  349.     fprintf (eport, "# %s file automatically generated by uuconv.\n", zport);
  350.  
  351.     switch (tinput)
  352.       {
  353.       case CONFIG_TAYLOR:
  354.     iret = uuconf_taylor_find_port (pinput, (const char *) NULL, 0L,
  355.                     0L, piportfn, (pointer) eport,
  356.                     &sport);
  357.     break;
  358.       case CONFIG_V2:
  359.     iret = uuconf_v2_find_port (pinput, (const char *) NULL, 0L, 0L,
  360.                     piportfn, (pointer) eport, &sport);
  361.     break;
  362.       case CONFIG_HDB:
  363.     iret = uuconf_hdb_find_port (pinput, (const char *) NULL, 0L, 0L,
  364.                      piportfn, (pointer) eport, &sport);
  365.     break;
  366.       }
  367.     
  368.     if (iret != UUCONF_NOT_FOUND)
  369.       uvuuconf_error (pinput, iret);
  370.  
  371.     if (ferror (eport)
  372.     || fclose (eport) == EOF)
  373.       {
  374.     fprintf (stderr, "uuchk:%s: error during output\n", zport);
  375.     exit (EXIT_FAILURE);
  376.       }
  377.   }
  378.  
  379.   /* V2 configuration files don't support dialers.  */
  380.   if (tinput != CONFIG_V2 && toutput != CONFIG_V2)
  381.     {
  382.       char **pzdialers;
  383.       char *zdialer;
  384.       char abtaylor[sizeof ZCURDIR + sizeof DIALFILE - 1];
  385.       char abhdb[sizeof ZCURDIR + sizeof HDB_DIALERS - 1];
  386.       FILE *edialer;
  387.       char **pz;
  388.  
  389.       /* Get the list of dialers.  */
  390.       switch (tinput)
  391.     {
  392.     default:
  393.     case CONFIG_TAYLOR:
  394.       iret = uuconf_taylor_dialer_names (pinput, &pzdialers);
  395.       break;
  396.     case CONFIG_HDB:
  397.       iret = uuconf_hdb_dialer_names (pinput, &pzdialers);
  398.       break;
  399.     }
  400.       if (iret != UUCONF_SUCCESS)
  401.     uvuuconf_error (pinput, iret);
  402.       else
  403.     {
  404.       /* Open the sys file for the output type.  */
  405.       switch (toutput)
  406.         {
  407.         default:
  408.         case CONFIG_TAYLOR:
  409.           sprintf (abtaylor, "%s%s", ZCURDIR, DIALFILE);
  410.           zdialer = abtaylor;
  411.           break;
  412.         case CONFIG_HDB:
  413.           sprintf (abhdb, "%s%s", ZCURDIR, HDB_DIALERS);
  414.           zdialer = abhdb;
  415.           break;
  416.         }
  417.       edialer = fopen (zdialer, "w");
  418.       if (edialer == NULL)
  419.         {
  420.           fprintf (stderr, "uuchk:%s: ", zdialer);
  421.           perror ("fopen");
  422.           exit (EXIT_FAILURE);
  423.         }
  424.  
  425.       fprintf (edialer, "# %s file automatically generated by uuconv.\n",
  426.            zdialer);
  427.  
  428.       /* Read and write each dialer.  */
  429.       for (pz = pzdialers; *pz != NULL; pz++)
  430.         {
  431.           struct uuconf_dialer sdialer;
  432.  
  433.           switch (tinput)
  434.         {
  435.         default:
  436.         case CONFIG_TAYLOR:
  437.           iret = uuconf_taylor_dialer_info (pinput, *pz, &sdialer);
  438.           break;
  439.         case CONFIG_HDB:
  440.           iret = uuconf_hdb_dialer_info (pinput, *pz, &sdialer);
  441.           break;
  442.         }
  443.           if (iret != UUCONF_SUCCESS)
  444.         uvuuconf_error (pinput, iret);
  445.           else
  446.         {
  447.           switch (toutput)
  448.             {
  449.             default:
  450.             case CONFIG_TAYLOR:
  451.               fprintf (edialer, "# Start of dialer %s\n",
  452.                    sdialer.uuconf_zname);
  453.               fprintf (edialer, "dialer %s\n", sdialer.uuconf_zname);
  454.               uvwrite_taylor_dialer (edialer, &sdialer, "");
  455.               break;
  456.             case CONFIG_HDB:
  457.               uvwrite_hdb_dialer (edialer, &sdialer);
  458.               break;
  459.             }
  460.           (void) uuconf_dialer_free (pinput, &sdialer);
  461.         }
  462.         }
  463.  
  464.       if (ferror (edialer)
  465.           || fclose (edialer) == EOF)
  466.         {
  467.           fprintf (stderr, "uuchk:%s: error during output\n", zdialer);
  468.           exit (EXIT_FAILURE);
  469.         }
  470.     }
  471.     }
  472.  
  473.   exit (EXIT_SUCCESS);
  474. }
  475.  
  476. /* Print out a usage message and die.  */
  477.  
  478. static void
  479. uvusage ()
  480. {
  481.   fprintf (stderr,
  482.        "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n",
  483.        VERSION);
  484.   fprintf (stderr,
  485.        "Usage: uuconv -i input -o output [-p program] [-I file]\n");
  486.   fprintf (stderr,
  487.        " -i input: Set input type (one of taylor, v2, hdb)\n");
  488.   fprintf (stderr,
  489.        " -o output: Set output type (one of taylor, v2, hdb)\n");
  490.   fprintf (stderr,
  491.        " -p program: Program to convert (e.g., uucp or cu)\n");
  492.   fprintf (stderr,
  493.        " -I file: Set Taylor UUCP configuration file to use\n");
  494.   exit (EXIT_FAILURE);
  495. }
  496.  
  497. /* Write out a timespan.  */
  498.  
  499. static void
  500. uvwrite_time (e, qtime)
  501.      FILE *e;
  502.      struct uuconf_timespan *qtime;
  503. {
  504.   if (qtime == NULL)
  505.     {
  506.       fprintf (e, "Never");
  507.       return;
  508.     }
  509.  
  510.   if (qtime->uuconf_istart == 0 && qtime->uuconf_iend == 7 * 24 * 60)
  511.     {
  512.       fprintf (e, "Any");
  513.       return;
  514.     }
  515.  
  516.   for (; qtime != NULL; qtime = qtime->uuconf_qnext)
  517.     {
  518.       int idaystart, idayend;
  519.       int ihourstart, ihourend;
  520.       int iminutestart, iminuteend;
  521.       const char * const zdays = "Su\0Mo\0Tu\0We\0Th\0Fr\0Sa";
  522.  
  523.       idaystart = qtime->uuconf_istart / (24 * 60);
  524.       ihourstart = (qtime->uuconf_istart % (24 * 60)) / 60;
  525.       iminutestart = qtime->uuconf_istart % 60;
  526.       if (qtime->uuconf_iend >= 7 * 24 * 60)
  527.     qtime->uuconf_iend = 7 * 24 * 60 - 1;
  528.       idayend = qtime->uuconf_iend / (24 * 60);
  529.       ihourend = (qtime->uuconf_iend % (24 * 60)) / 60;
  530.       iminuteend = qtime->uuconf_iend % 60;
  531.       if (ihourend == 0 && iminuteend == 0)
  532.     --idayend;
  533.  
  534.       if (idaystart == idayend)
  535.     fprintf (e, "%s%02d%02d-%02d%02d", zdays + idaystart * 3,
  536.          ihourstart, iminutestart, ihourend, iminuteend);
  537.       else
  538.     {
  539.       int i;
  540.  
  541.       fprintf (e, "%s%02d%02d-0000", zdays + idaystart * 3,
  542.            ihourstart, iminutestart);
  543.       for (i = idaystart + 1; i < idayend; i++)
  544.         fprintf (e, ",%s", zdays + i * 3);
  545.       if (ihourend != 0 || iminuteend != 0)
  546.         fprintf (e, ",%s0000-%02d%02d", zdays + idayend * 3, ihourend,
  547.              iminuteend);
  548.     }
  549.  
  550.       if (qtime->uuconf_qnext != NULL)
  551.     fprintf (e, ",");
  552.     }
  553. }
  554.  
  555. /* Some subroutines used when writing out Taylor UUCP configuration
  556.    files.  */
  557.  
  558. /* Write a command with a string argument.  */
  559.  
  560. static void
  561. uvwrite_string (e, zarg, zcmd)
  562.      FILE *e;
  563.      const char *zarg;
  564.      const char *zcmd;
  565. {
  566.   if (zarg != (const char *) &_uuconf_unset)
  567.     fprintf (e, "%s %s\n", zcmd, zarg == NULL ? (const char *) "" : zarg);
  568. }
  569.  
  570. /* Write out a size restriction command.  */
  571.  
  572. static void
  573. uvwrite_size (e, qtime, zcmd)
  574.      FILE *e;
  575.      struct uuconf_timespan *qtime;
  576.      const char *zcmd;
  577. {
  578.   if (qtime != (struct uuconf_timespan *) &_uuconf_unset)
  579.     {
  580.       for (; qtime != NULL; qtime = qtime->uuconf_qnext)
  581.     {
  582.       fprintf (e, "%s %ld", zcmd, qtime->uuconf_ival);
  583.       uvwrite_time (e, qtime);
  584.       fprintf (e, "\n");
  585.     }
  586.     }
  587. }
  588.  
  589. /* Write out a boolean argument with a string command.  If the value
  590.    is less than zero, than it was uninitialized and we don't write
  591.    anything.  */
  592.  
  593. static void
  594. uvwrite_boolean (e, fval, zcmd)
  595.      FILE *e;
  596.      int fval;
  597.      const char *zcmd;
  598. {
  599.   if (fval >= 0)
  600.     fprintf (e, "%s %s\n", zcmd, fval > 0 ? "true" : "false");
  601. }
  602.  
  603. /* Write out a string array as a single command.  */
  604.  
  605. static void
  606. uvwrite_string_array (e, pz, zcmd)
  607.      FILE *e;
  608.      char **pz;
  609.      const char *zcmd;
  610. {
  611.   if (pz != (char **) &_uuconf_unset)
  612.     {
  613.       fprintf (e, "%s", zcmd);
  614.       if (pz != NULL)
  615.     for (; *pz != NULL; pz++)
  616.       fprintf (e, " %s", *pz);
  617.       fprintf (e, "\n");
  618.     }
  619. }
  620.  
  621. /* Write out a chat script.  Don't separate subsend/subexpect strings
  622.    by spaces.  */
  623.  
  624. static void
  625. uvwrite_chat_script (e, pzarg)
  626.      FILE *e;
  627.      char **pzarg;
  628. {
  629.   char **pz;
  630.  
  631.   if (pzarg == NULL || pzarg == (char **) &_uuconf_unset)
  632.     return;
  633.  
  634.   for (pz = pzarg; *pz != NULL; pz++)
  635.     {
  636.       if ((*pz)[0] != '-' && pz != pzarg)
  637.     fprintf (e, " ");
  638.       fprintf (e, *pz);
  639.     }
  640. }
  641.  
  642. /* Write out chat information.  If the qlast argument is not NULL,
  643.    then only values that are different from qlast should be written.
  644.    The fforce argument is used to get around a peculiar problem: if
  645.    the ``chat'' command is used with no arguments for a system, then
  646.    uuconf_pzchat will be NULL (not &_uuconf_unset) and the default
  647.    chat script will not be used.  We must distinguish this case from
  648.    the ``chat'' command not appearing at all for a port or dialer, in
  649.    which case the value will again be NULL.  In the former case we
  650.    must output a ``chat'' command, in the latter case we would prefer
  651.    not to.  */
  652.  
  653. static void
  654. uvwrite_chat (e, q, qlast, zprefix, fforce)
  655.      FILE *e;
  656.      const struct uuconf_chat *q;
  657.      const struct uuconf_chat *qlast;
  658.      const char *zprefix;
  659.      boolean fforce;
  660. {
  661.   char **pz;
  662.   char ab[100];
  663.  
  664.   if (q->uuconf_pzchat != (char **) &_uuconf_unset
  665.       && (qlast == NULL
  666.       ? (fforce || q->uuconf_pzchat != NULL)
  667.       : qlast->uuconf_pzchat != q->uuconf_pzchat))
  668.     {
  669.       fprintf (e, "%schat ", zprefix);
  670.       uvwrite_chat_script (e, q->uuconf_pzchat);
  671.       fprintf (e, "\n");
  672.     }
  673.  
  674.   if (q->uuconf_pzprogram != (char **) &_uuconf_unset
  675.       && (qlast == NULL
  676.       ? q->uuconf_pzprogram != NULL
  677.       : qlast->uuconf_pzprogram != q->uuconf_pzprogram))
  678.     {
  679.       sprintf (ab, "%schat-program", zprefix);
  680.       uvwrite_string_array (e, q->uuconf_pzprogram, ab);
  681.     }
  682.  
  683.   if (q->uuconf_ctimeout >= 0
  684.       && (qlast == NULL
  685.       || qlast->uuconf_ctimeout != q->uuconf_ctimeout))
  686.     fprintf (e, "%schat-timeout %d\n", zprefix, q->uuconf_ctimeout);
  687.  
  688.   if (q->uuconf_pzfail != NULL
  689.       && q->uuconf_pzfail != (char **) &_uuconf_unset
  690.       && (qlast == NULL
  691.       || qlast->uuconf_pzfail != q->uuconf_pzfail))
  692.     for (pz = q->uuconf_pzfail; *pz != NULL; pz++)
  693.       fprintf (e, "%schat-fail %s\n", zprefix, *pz);
  694.       
  695.   if (qlast == NULL || qlast->uuconf_fstrip != q->uuconf_fstrip)
  696.     {
  697.       sprintf (ab, "%schat-strip", zprefix);
  698.       uvwrite_boolean (e, q->uuconf_fstrip, ab);
  699.     }
  700. }
  701.  
  702. /* Write out protocol parameters to a Taylor UUCP file.  */
  703.  
  704. static void
  705. uvwrite_proto_params (e, qparams, zprefix)
  706.      FILE *e;
  707.      const struct uuconf_proto_param *qparams;
  708.      const char *zprefix;
  709. {
  710.   const struct uuconf_proto_param *qp;
  711.  
  712.   if (qparams == NULL
  713.       || qparams == (struct uuconf_proto_param *) &_uuconf_unset)
  714.     return;
  715.  
  716.   for (qp = qparams; qp->uuconf_bproto != '\0'; qp++)
  717.     {
  718.       const struct uuconf_proto_param_entry *qe;
  719.  
  720.       for (qe = qp->uuconf_qentries; qe->uuconf_cargs > 0; qe++)
  721.     {
  722.       int i;
  723.  
  724.       fprintf (e, "%sprotocol-parameter %c", zprefix, qp->uuconf_bproto);
  725.       for (i = 0; i < qe->uuconf_cargs; i++)
  726.         fprintf (e, " %s", qe->uuconf_pzargs[i]);
  727.       fprintf (e, "\n");
  728.     }
  729.     }
  730. }
  731.  
  732. /* Write out Taylor UUCP system information.  */
  733.  
  734. static void
  735. uvwrite_taylor_system (e, q)
  736.      FILE *e;
  737.      const struct uuconf_system *q;
  738. {
  739.   char **pz;
  740.   const struct uuconf_system *qlast;
  741.  
  742.   fprintf (e, "# Start of system %s\n", q->uuconf_zname);
  743.  
  744.   fprintf (e, "system %s\n", q->uuconf_zname);
  745.   if (q->uuconf_pzalias != NULL
  746.       && q->uuconf_pzalias != (char **) &_uuconf_unset)
  747.     for (pz = q->uuconf_pzalias; *pz != NULL; pz++)
  748.       uvwrite_string (e, *pz, "alias");
  749.  
  750.   for (qlast = NULL; q != NULL; qlast = q, q = q->uuconf_qalternate)
  751.     {
  752.       struct uuconf_timespan *qtime;
  753.  
  754.       if (qlast != NULL)
  755.     {
  756.       fprintf (e, "alternate");
  757.       if (q->uuconf_zalternate != (char *) &_uuconf_unset
  758.           && q->uuconf_zalternate != NULL)
  759.         fprintf (e, " %s", q->uuconf_zalternate);
  760.       fprintf (e, "\n");
  761.     }
  762.  
  763. #define CHANGED(x) (qlast == NULL || qlast->x != q->x)
  764.  
  765.       if (CHANGED (uuconf_qtimegrade)
  766.       && (q->uuconf_qtimegrade
  767.           != (struct uuconf_timespan *) &_uuconf_unset))
  768.     {
  769.       if (q->uuconf_qtimegrade == NULL)
  770.         fprintf (e, "time never\n");
  771.       else
  772.         {
  773.           for (qtime = q->uuconf_qtimegrade;
  774.            qtime != NULL;
  775.            qtime = qtime->uuconf_qnext)
  776.         {
  777.           if ((char) qtime->uuconf_ival == UUCONF_GRADE_LOW)
  778.             fprintf (e, "time ");
  779.           else
  780.             fprintf (e, "timegrade %c ", (char) qtime->uuconf_ival);
  781.           uvwrite_time (e, qtime);
  782.           if (qtime->uuconf_cretry != 0)
  783.             fprintf (e, " %d", qtime->uuconf_cretry);
  784.           fprintf (e, "\n");
  785.         }
  786.         }
  787.     }
  788.  
  789.       if (CHANGED (uuconf_qcalltimegrade)
  790.       && (q->uuconf_qcalltimegrade
  791.           != (struct uuconf_timespan *) &_uuconf_unset))
  792.     {
  793.       for (qtime = q->uuconf_qcalltimegrade;
  794.            qtime != NULL;
  795.            qtime = qtime->uuconf_qnext)
  796.         {
  797.           fprintf (e, "call-timegrade %c ", (char) qtime->uuconf_ival);
  798.           uvwrite_time (e, qtime);
  799.           fprintf (e, "\n");
  800.         }
  801.     }
  802.  
  803.       if (CHANGED (uuconf_qcall_local_size))
  804.     uvwrite_size (e, q->uuconf_qcall_local_size, "call-local-size");
  805.  
  806.       if (CHANGED (uuconf_qcall_remote_size))
  807.     uvwrite_size (e, q->uuconf_qcall_remote_size, "call-remote-size");
  808.  
  809.       if (CHANGED (uuconf_qcalled_local_size))
  810.     uvwrite_size (e, q->uuconf_qcalled_local_size, "called-local-size");
  811.  
  812.       if (CHANGED (uuconf_qcalled_remote_size))
  813.     uvwrite_size (e, q->uuconf_qcalled_remote_size, "called-remote-size");
  814.  
  815.       if (CHANGED (uuconf_ibaud) || CHANGED (uuconf_ihighbaud))
  816.     {
  817.       if (q->uuconf_ibaud >= 0)
  818.         {
  819.           if (q->uuconf_ihighbaud > 0)
  820.         fprintf (e, "baud-range %ld %ld\n", q->uuconf_ibaud,
  821.              q->uuconf_ihighbaud);
  822.           else
  823.         fprintf (e, "baud %ld\n", q->uuconf_ibaud);
  824.         }
  825.     }
  826.  
  827.       if (CHANGED (uuconf_zport) || CHANGED (uuconf_qport))
  828.     {
  829.       if (q->uuconf_zport != NULL
  830.           && q->uuconf_zport != (char *) &_uuconf_unset)
  831.         uvwrite_string (e, q->uuconf_zport, "port");
  832.       else if (q->uuconf_qport != NULL
  833.            && (q->uuconf_qport
  834.                != (struct uuconf_port *) &_uuconf_unset))
  835.         uvwrite_taylor_port (e, q->uuconf_qport, "port ");
  836.     }
  837.  
  838.       if (CHANGED (uuconf_zphone))
  839.     {
  840.       const char *zcmd;
  841.  
  842.       if (q->uuconf_qport != NULL
  843.           && q->uuconf_qport != (struct uuconf_port *) &_uuconf_unset
  844.           && (q->uuconf_qport->uuconf_ttype == UUCONF_PORTTYPE_TCP
  845.           || q->uuconf_qport->uuconf_ttype == UUCONF_PORTTYPE_TLI))
  846.         zcmd = "address";
  847.       else
  848.         zcmd = "phone";
  849.       uvwrite_string (e, q->uuconf_zphone, zcmd);
  850.     }
  851.  
  852.       uvwrite_chat (e, &q->uuconf_schat,
  853.             (qlast == NULL
  854.              ? (struct uuconf_chat *) NULL
  855.              : &qlast->uuconf_schat),
  856.             "", TRUE);
  857.  
  858.       if (CHANGED (uuconf_zcall_login))
  859.     uvwrite_string (e, q->uuconf_zcall_login, "call-login");
  860.  
  861.       if (CHANGED (uuconf_zcall_password))
  862.     uvwrite_string (e, q->uuconf_zcall_password, "call-password");
  863.  
  864.       if (CHANGED (uuconf_zcalled_login))
  865.     uvwrite_string (e, q->uuconf_zcalled_login, "called-login");
  866.  
  867.       if (CHANGED (uuconf_fcallback))
  868.     uvwrite_boolean (e, q->uuconf_fcallback, "callback");
  869.  
  870.       if (CHANGED (uuconf_fsequence))
  871.     uvwrite_boolean (e, q->uuconf_fsequence, "sequence");
  872.  
  873.       if (CHANGED (uuconf_zprotocols))
  874.     uvwrite_string (e, q->uuconf_zprotocols, "protocol");
  875.  
  876.       if (CHANGED (uuconf_qproto_params))
  877.     uvwrite_proto_params (e, q->uuconf_qproto_params, "");
  878.       
  879.       uvwrite_chat (e, &q->uuconf_scalled_chat,
  880.             (qlast == NULL
  881.              ? (struct uuconf_chat *) NULL
  882.              : &qlast->uuconf_scalled_chat),
  883.             "called-", FALSE);
  884.  
  885.       if (CHANGED (uuconf_zdebug))
  886.     uvwrite_string (e, q->uuconf_zdebug, "debug");
  887.  
  888.       if (CHANGED (uuconf_zmax_remote_debug))
  889.     uvwrite_string (e, q->uuconf_zmax_remote_debug, "max-remote-debug");
  890.  
  891.       if ((CHANGED (uuconf_fsend_request)
  892.        || CHANGED (uuconf_frec_request))
  893.       && (q->uuconf_fsend_request >= 0
  894.           || q->uuconf_frec_request >= 0))
  895.     {
  896.       if (q->uuconf_fsend_request >= 0
  897.           && (q->uuconf_fsend_request > 0
  898.           ? q->uuconf_frec_request > 0
  899.           : q->uuconf_frec_request == 0))
  900.         uvwrite_boolean (e, q->uuconf_fsend_request, "request");
  901.       else
  902.         {
  903.           uvwrite_boolean (e, q->uuconf_fsend_request, "send-request");
  904.           uvwrite_boolean (e, q->uuconf_frec_request,
  905.                    "receive-request");
  906.         }
  907.     }
  908.  
  909.       if ((CHANGED (uuconf_fcall_transfer)
  910.        || CHANGED (uuconf_fcalled_transfer))
  911.       && (q->uuconf_fcall_transfer >= 0
  912.           || q->uuconf_fcalled_transfer >= 0))
  913.     {
  914.       if (q->uuconf_fcall_transfer >= 0
  915.           && (q->uuconf_fcall_transfer > 0
  916.           ? q->uuconf_fcalled_transfer > 0
  917.           : q->uuconf_fcalled_transfer == 0))
  918.         uvwrite_boolean (e, q->uuconf_fcall_transfer, "transfer");
  919.       else
  920.         {
  921.           uvwrite_boolean (e, q->uuconf_fcall_transfer, "call-transfer");
  922.           uvwrite_boolean (e, q->uuconf_fcalled_transfer,
  923.                    "called-transfer");
  924.         }
  925.     }
  926.  
  927.       if (CHANGED (uuconf_pzlocal_send))
  928.     uvwrite_string_array (e, q->uuconf_pzlocal_send, "local-send");
  929.  
  930.       if (CHANGED (uuconf_pzremote_send))
  931.     uvwrite_string_array (e, q->uuconf_pzremote_send, "remote-send");
  932.  
  933.       if (CHANGED (uuconf_pzlocal_receive))
  934.     uvwrite_string_array (e, q->uuconf_pzlocal_receive, "local-receive");
  935.  
  936.       if (CHANGED (uuconf_pzremote_receive))
  937.     uvwrite_string_array (e, q->uuconf_pzremote_receive,
  938.                   "remote-receive");
  939.  
  940.       if (CHANGED (uuconf_pzpath))
  941.     uvwrite_string_array (e, q->uuconf_pzpath, "command-path");
  942.  
  943.       if (CHANGED (uuconf_pzcmds))
  944.     uvwrite_string_array (e, q->uuconf_pzcmds, "commands");
  945.  
  946.       if (CHANGED (uuconf_cfree_space)
  947.       && q->uuconf_cfree_space >= 0)
  948.     fprintf (e, "free-space %ld\n", q->uuconf_cfree_space);
  949.  
  950.       if (CHANGED (uuconf_pzforward_from))
  951.     uvwrite_string_array (e, q->uuconf_pzforward_from, "forward-from");
  952.  
  953.       if (CHANGED (uuconf_pzforward_to))
  954.     uvwrite_string_array (e, q->uuconf_pzforward_to, "forward-to");
  955.  
  956.       if (CHANGED (uuconf_zpubdir))
  957.     uvwrite_string (e, q->uuconf_zpubdir, "pubdir");
  958.  
  959.       if (CHANGED (uuconf_zlocalname))
  960.     uvwrite_string (e, q->uuconf_zlocalname, "myname");
  961.     }
  962. }
  963.  
  964. /* Write out V2 system information.  */
  965.  
  966. static void
  967. uvwrite_v2_system (e, q)
  968.      FILE *e;
  969.      const struct uuconf_system *q;
  970. {
  971.   for (; q != NULL; q = q->uuconf_qalternate)
  972.     {
  973.       fprintf (e, "%s", q->uuconf_zname);
  974.  
  975.       if (q->uuconf_qtimegrade != (struct uuconf_timespan *) &_uuconf_unset)
  976.     {
  977.       fprintf (e, " ");
  978.       uvwrite_time (e, q->uuconf_qtimegrade);
  979.  
  980.       if (q->uuconf_zport != (char *) &_uuconf_unset
  981.           || q->uuconf_qport != (struct uuconf_port *) &_uuconf_unset)
  982.         {
  983.           struct uuconf_port *qp;
  984.           boolean ftcp;
  985.  
  986.           qp = q->uuconf_qport;
  987.           ftcp = (qp != (struct uuconf_port *) &_uuconf_unset
  988.               && qp != NULL
  989.               && qp->uuconf_ttype == UUCONF_PORTTYPE_TCP);
  990.           if (ftcp
  991.           || (q->uuconf_zport != NULL
  992.               && q->uuconf_zport != (char *) &_uuconf_unset))
  993.         {
  994.           if (ftcp)
  995.             fprintf (e, " TCP");
  996.           else
  997.             fprintf (e, " %s", q->uuconf_zport);
  998.  
  999.           if (ftcp || q->uuconf_ibaud >= 0)
  1000.             {
  1001.               fprintf (e, " ");
  1002.               if (ftcp)
  1003.             {
  1004.               const char *zport;
  1005.  
  1006.               zport = qp->uuconf_u.uuconf_stcp.uuconf_zport;
  1007.               if (zport == NULL)
  1008.                 zport = "uucp";
  1009.               fprintf (e, "%s", zport);
  1010.             }
  1011.               else
  1012.             fprintf (e, "%ld", q->uuconf_ibaud);
  1013.  
  1014.               if (q->uuconf_zphone != (char *) &_uuconf_unset
  1015.               && q->uuconf_zphone != NULL)
  1016.             {
  1017.               char **pzc;
  1018.               
  1019.               fprintf (e, " %s", q->uuconf_zphone);
  1020.               pzc = q->uuconf_schat.uuconf_pzchat;
  1021.               if (pzc != (char **) &_uuconf_unset
  1022.                   && pzc != NULL)
  1023.                 {
  1024.                   fprintf (e, " ");
  1025.                   uvwrite_chat_script (e, pzc);
  1026.                 }
  1027.             }
  1028.             }
  1029.         }
  1030.         }
  1031.     }
  1032.  
  1033.       fprintf (e, "\n");
  1034.  
  1035.       /* Here we should gather information to write out to USERFILE
  1036.      and L.cmds, and perhaps some day we will.  It's much more
  1037.      likely to happen if somebody else does it, though.  */
  1038.     }
  1039. }
  1040.  
  1041. /* Write out HDB system information.  */
  1042.  
  1043. static void
  1044. uvwrite_hdb_system (e, qsys)
  1045.      FILE *e;
  1046.      const struct uuconf_system *qsys;
  1047. {
  1048.   const struct uuconf_system *q;
  1049.   struct shpermissions sperm;
  1050.   char *azmachine[2];
  1051.   char *azlogname[2];
  1052.  
  1053.   for (q = qsys; q != NULL; q = q->uuconf_qalternate)
  1054.     {
  1055.       if (q->uuconf_fcall)
  1056.     {
  1057.       fprintf (e, "%s", q->uuconf_zname);
  1058.  
  1059.       if (q->uuconf_qtimegrade
  1060.           != (struct uuconf_timespan *) &_uuconf_unset)
  1061.         {
  1062.           const char *zport;
  1063.  
  1064.           fprintf (e, " ");
  1065.           uvwrite_time (e, q->uuconf_qtimegrade);
  1066.  
  1067.           zport = q->uuconf_zport;
  1068.           if (q->uuconf_qport != NULL
  1069.           && q->uuconf_qport != (struct uuconf_port *) &_uuconf_unset
  1070.           && q->uuconf_qport->uuconf_ttype == UUCONF_PORTTYPE_TCP)
  1071.         zport = "TCP";
  1072.           if (zport != NULL && zport != (char *) &_uuconf_unset)
  1073.         {
  1074.           fprintf (e, " %s", zport);
  1075.           if (q->uuconf_zprotocols != (char *) &_uuconf_unset
  1076.               && q->uuconf_zprotocols != NULL)
  1077.             fprintf (e, ",%s", q->uuconf_zprotocols);
  1078.  
  1079.           if (q->uuconf_ibaud >= 0
  1080.               || q->uuconf_zphone != (char *) &_uuconf_unset)
  1081.             {
  1082.               fprintf (e, " ");
  1083.               if (q->uuconf_ibaud < 0)
  1084.             fprintf (e, "Any");
  1085.               else
  1086.             {
  1087.               fprintf (e, "%ld", q->uuconf_ibaud);
  1088.               if (q->uuconf_ihighbaud >= 0)
  1089.                 fprintf (e, "-%ld", q->uuconf_ihighbaud);
  1090.             }
  1091.  
  1092.               if (q->uuconf_zphone != (char *) &_uuconf_unset
  1093.               && q->uuconf_zphone != NULL)
  1094.             {
  1095.               char **pzc;
  1096.               
  1097.               fprintf (e, " %s", q->uuconf_zphone);
  1098.               pzc = q->uuconf_schat.uuconf_pzchat;
  1099.               if (pzc != (char **) &_uuconf_unset
  1100.                   && pzc != NULL)
  1101.                 {
  1102.                   fprintf (e, " ");
  1103.                   uvwrite_chat_script (e, pzc);
  1104.                 }
  1105.             }
  1106.             }
  1107.         }
  1108.         }
  1109.  
  1110.       fprintf (e, "\n");
  1111.     }
  1112.     }
  1113.  
  1114.   /* Build a Permissions entry for this system.  There will be only
  1115.      one MACHINE entry for a given system.  */
  1116.  
  1117.   for (q = qsys; q != NULL; q = q->uuconf_qalternate)
  1118.     if (q->uuconf_fcall)
  1119.       break;
  1120.  
  1121.   if (q != NULL)
  1122.     {
  1123.       sperm.qnext = NULL;
  1124.       sperm.pzlogname = NULL;
  1125.       sperm.pzmachine = NULL;
  1126.       sperm.frequest = -1;
  1127.       sperm.fsendfiles = -1;
  1128.       sperm.pzread = NULL;
  1129.       sperm.pzwrite = NULL;
  1130.       sperm.fcallback = -1;
  1131.       sperm.pzcommands = NULL;
  1132.       sperm.pzvalidate = NULL;
  1133.       sperm.zmyname = NULL;
  1134.       sperm.zpubdir = NULL;
  1135.       sperm.pzalias = NULL;
  1136.  
  1137.       azmachine[0] = q->uuconf_zname;
  1138.       azmachine[1] = NULL;
  1139.       sperm.pzmachine = azmachine;
  1140.       if (q->uuconf_fsend_request >= 0)
  1141.     sperm.frequest = q->uuconf_fsend_request;
  1142.       if (q->uuconf_pzremote_send != (char **) &_uuconf_unset
  1143.       && q->uuconf_pzremote_send != NULL)
  1144.     sperm.pzread = q->uuconf_pzremote_send;
  1145.       if (q->uuconf_pzremote_receive != (char **) &_uuconf_unset
  1146.       && q->uuconf_pzremote_receive != NULL)
  1147.     sperm.pzwrite = q->uuconf_pzremote_receive;
  1148.       if (q->uuconf_pzcmds != (char **) &_uuconf_unset
  1149.       && q->uuconf_pzcmds != NULL)
  1150.     sperm.pzcommands = q->uuconf_pzcmds;
  1151.       if (q->uuconf_zlocalname != (char *) &_uuconf_unset
  1152.       && q->uuconf_zlocalname != NULL)
  1153.     sperm.zmyname = q->uuconf_zlocalname;
  1154.       if (q->uuconf_zpubdir != (char *) &_uuconf_unset
  1155.       && q->uuconf_zpubdir != NULL)
  1156.     sperm.zpubdir = q->uuconf_zpubdir;
  1157.       if (q->uuconf_pzalias != (char **) &_uuconf_unset
  1158.       && q->uuconf_pzalias != NULL)
  1159.     sperm.pzalias = q->uuconf_pzalias;
  1160.  
  1161.       if (q->uuconf_fcalled
  1162.       && q->uuconf_zcalled_login != (char *) &_uuconf_unset
  1163.       && q->uuconf_zcalled_login != NULL)
  1164.     {
  1165.       azlogname[0] = q->uuconf_zcalled_login;
  1166.       azlogname[1] = NULL;
  1167.       sperm.pzlogname = azlogname;
  1168.       if (q->uuconf_fcalled_transfer >= 0)
  1169.         sperm.fsendfiles = q->uuconf_fcalled_transfer;
  1170.       if (q->uuconf_fcallback >= 0)
  1171.         sperm.fcallback = q->uuconf_fcallback;
  1172.       sperm.pzvalidate = azmachine;
  1173.     }
  1174.  
  1175.       uvadd_perm (&sperm);
  1176.     }
  1177.  
  1178.   /* Now add a Permissions entry for each alternative that is not used
  1179.      for calling out.  */
  1180.   for (q = qsys; q != NULL; q = q->uuconf_qalternate)
  1181.     {
  1182.       if (! q->uuconf_fcalled || q->uuconf_fcall)
  1183.     continue;
  1184.  
  1185.       sperm.qnext = NULL;
  1186.       sperm.pzlogname = NULL;
  1187.       sperm.pzmachine = NULL;
  1188.       sperm.frequest = -1;
  1189.       sperm.fsendfiles = -1;
  1190.       sperm.pzread = NULL;
  1191.       sperm.pzwrite = NULL;
  1192.       sperm.fcallback = -1;
  1193.       sperm.pzcommands = NULL;
  1194.       sperm.pzvalidate = NULL;
  1195.       sperm.zmyname = NULL;
  1196.       sperm.zpubdir = NULL;
  1197.       sperm.pzalias = NULL;
  1198.  
  1199.       if (q->uuconf_zcalled_login != (char *) &_uuconf_unset
  1200.       && q->uuconf_zcalled_login != NULL)
  1201.     azlogname[0] = q->uuconf_zcalled_login;
  1202.       else
  1203.     azlogname[0] = (char *) "OTHER";
  1204.       azlogname[1] = NULL;
  1205.       sperm.pzlogname = azlogname;
  1206.  
  1207.       if (q->uuconf_fsend_request >= 0)
  1208.     sperm.frequest = q->uuconf_fsend_request;
  1209.       if (q->uuconf_fcalled_transfer >= 0)
  1210.     sperm.fsendfiles = q->uuconf_fcalled_transfer;
  1211.       if (q->uuconf_pzremote_send != (char **) &_uuconf_unset
  1212.       && q->uuconf_pzremote_send != NULL)
  1213.     sperm.pzread = q->uuconf_pzremote_send;
  1214.       if (q->uuconf_pzremote_receive != (char **) &_uuconf_unset
  1215.       && q->uuconf_pzremote_receive != NULL)
  1216.     sperm.pzwrite = q->uuconf_pzremote_receive;
  1217.       if (q->uuconf_fcallback >= 0)
  1218.     sperm.fcallback = q->uuconf_fcallback;
  1219.       if (q->uuconf_zlocalname != (char *) &_uuconf_unset
  1220.       && q->uuconf_zlocalname != NULL)
  1221.     sperm.zmyname = q->uuconf_zlocalname;
  1222.       if (q->uuconf_zpubdir != (char *) &_uuconf_unset
  1223.       && q->uuconf_zpubdir != NULL)
  1224.     sperm.zpubdir = q->uuconf_zpubdir;
  1225.  
  1226.       uvadd_perm (&sperm);
  1227.     }
  1228. }
  1229.  
  1230. /* Compare two strings from a Permissions entry, returning TRUE if
  1231.    they are the same.  */
  1232. static boolean
  1233. fvperm_string_cmp (z1, z2)
  1234.      const char *z1;
  1235.      const char *z2;
  1236. {
  1237.   if (z1 == NULL
  1238.       ? z2 != NULL
  1239.       : z2 == NULL)
  1240.     return FALSE;
  1241.  
  1242.   if (z1 == NULL)
  1243.     return TRUE;
  1244.  
  1245.   return strcmp (z1, z2) == 0;
  1246. }
  1247.  
  1248. /* Compare two arrays of strings from a Permissions entry, returning
  1249.    TRUE if they are the same.  */
  1250.  
  1251. static boolean
  1252. fvperm_array_cmp (pz1, pz2)
  1253.      const char **pz1;
  1254.      const char **pz2;
  1255. {
  1256.   if (pz1 == NULL
  1257.       ? pz2 != NULL
  1258.       : pz2 == NULL)
  1259.     return FALSE;
  1260.  
  1261.   if (pz1 == NULL)
  1262.     return TRUE;
  1263.  
  1264.   for (; *pz1 != NULL && *pz2 != NULL; pz1++, pz2++)
  1265.     if (strcmp (*pz1, *pz2) != 0)
  1266.       break;
  1267.  
  1268.   return *pz1 == NULL && *pz2 == NULL;
  1269. }      
  1270.  
  1271. /* Add a Permissions entry to a global list, combining entries where
  1272.    possible.  */
  1273.  
  1274. static void
  1275. uvadd_perm (qadd)
  1276.      struct shpermissions *qadd;
  1277. {
  1278.   struct shpermissions *qlook;
  1279.   struct shpermissions *qnew;
  1280.   int iret;
  1281.  
  1282.   /* If there's no information, don't bother to add this entry.  */
  1283.   if (qadd->pzlogname == NULL
  1284.       && qadd->frequest < 0
  1285.       && qadd->fsendfiles < 0
  1286.       && qadd->pzread == NULL
  1287.       && qadd->pzwrite == NULL
  1288.       && qadd->fcallback < 0
  1289.       && qadd->pzcommands == NULL
  1290.       && qadd->pzvalidate == NULL
  1291.       && qadd->zmyname == NULL
  1292.       && qadd->zpubdir == NULL
  1293.       && qadd->pzalias == NULL)
  1294.     return;
  1295.  
  1296.   for (qlook = qVperms; qlook != NULL; qlook = qlook->qnext)
  1297.     {
  1298.       /* See if we can merge qadd into qlook.  */
  1299.       if (qadd->pzlogname == NULL
  1300.       ? qlook->pzlogname != NULL
  1301.       : qlook->pzlogname == NULL)
  1302.     continue;
  1303.       if (qadd->pzmachine == NULL
  1304.       ? qlook->pzmachine != NULL
  1305.       : qlook->pzmachine == NULL)
  1306.     continue;
  1307.       if (qadd->frequest != qlook->frequest
  1308.       || qadd->fsendfiles != qlook->fsendfiles
  1309.       || qadd->fcallback != qlook->fcallback)
  1310.     continue;
  1311.       if (! fvperm_string_cmp (qadd->zmyname, qlook->zmyname)
  1312.       || ! fvperm_string_cmp (qadd->zpubdir, qlook->zpubdir))
  1313.     continue;
  1314.       if (! fvperm_array_cmp ((const char **) qadd->pzread,
  1315.                   (const char **) qlook->pzread)
  1316.       || ! fvperm_array_cmp ((const char **)  qadd->pzwrite,
  1317.                  (const char **) qlook->pzwrite)
  1318.       || ! fvperm_array_cmp ((const char **) qadd->pzcommands,
  1319.                  (const char **) qlook->pzcommands))
  1320.     continue;
  1321.  
  1322.       /* Merge qadd into qlook.  */
  1323.       if (qadd->pzmachine != NULL)
  1324.     {
  1325.       iret = _uuconf_iadd_string ((struct sglobal *) NULL,
  1326.                       qadd->pzmachine[0], FALSE,
  1327.                       TRUE, &qlook->pzmachine,
  1328.                       (pointer) NULL);
  1329.       if (iret != UUCONF_SUCCESS)
  1330.         uvuuconf_error ((pointer) NULL, iret);
  1331.     }
  1332.       if (qadd->pzlogname != NULL)
  1333.     {
  1334.       iret = _uuconf_iadd_string ((struct sglobal *) NULL,
  1335.                       qadd->pzlogname[0], FALSE,
  1336.                       TRUE, &qlook->pzlogname,
  1337.                       (pointer) NULL);
  1338.       if (iret != UUCONF_SUCCESS)
  1339.         uvuuconf_error ((pointer) NULL, iret);
  1340.     }
  1341.       if (qadd->pzalias != NULL)
  1342.     {
  1343.       char **pz;
  1344.  
  1345.       for (pz = qadd->pzalias; *pz != NULL; pz++)
  1346.         {
  1347.           iret = _uuconf_iadd_string ((struct sglobal *) NULL,
  1348.                       *pz, FALSE, TRUE,
  1349.                       &qlook->pzalias, (pointer) NULL);
  1350.           if (iret != UUCONF_SUCCESS)
  1351.         uvuuconf_error ((pointer) NULL, iret);
  1352.         }
  1353.     }
  1354.  
  1355.       return;
  1356.     }
  1357.  
  1358.   /* We must add qadd as a new entry on the list, which means we must
  1359.      copy it into the heap.  */
  1360.  
  1361.   qnew = (struct shpermissions *) malloc (sizeof (struct shpermissions));
  1362.   if (qnew == NULL)
  1363.     uvuuconf_error ((pointer) NULL, UUCONF_MALLOC_FAILED);
  1364.   *qnew = *qadd;
  1365.   if (qadd->pzmachine != NULL)
  1366.     {
  1367.       qnew->pzmachine = NULL;
  1368.       iret = _uuconf_iadd_string ((struct sglobal *) NULL,
  1369.                   qadd->pzmachine[0], FALSE,
  1370.                   FALSE, &qnew->pzmachine,
  1371.                   (pointer) NULL);
  1372.       if (iret != UUCONF_SUCCESS)
  1373.     uvuuconf_error ((pointer) NULL, iret);
  1374.     }
  1375.   if (qadd->pzlogname != NULL)
  1376.     {
  1377.       qnew->pzlogname = NULL;
  1378.       iret = _uuconf_iadd_string ((struct sglobal *) NULL,
  1379.                   qadd->pzlogname[0], FALSE,
  1380.                   FALSE, &qnew->pzlogname,
  1381.                   (pointer) NULL);
  1382.       if (iret != UUCONF_SUCCESS)
  1383.     uvuuconf_error ((pointer) NULL, iret);
  1384.     }
  1385.   if (qadd->pzvalidate != NULL)
  1386.     qnew->pzvalidate = qnew->pzmachine;
  1387.  
  1388.   qnew->qnext = qVperms;
  1389.   qVperms = qnew;
  1390. }
  1391.  
  1392. /* Write out the Permissions entries.  */
  1393.  
  1394. static void
  1395. uvwrite_perms ()
  1396. {
  1397.   char ab[sizeof ZCURDIR + sizeof HDB_PERMISSIONS - 1];
  1398.   FILE *e;
  1399.   struct shpermissions *q;
  1400.  
  1401.   sprintf (ab, "%s%s", ZCURDIR, HDB_PERMISSIONS);
  1402.   e = fopen (ab, "w");
  1403.   if (e == NULL)
  1404.     {
  1405.       fprintf (stderr, "uuchk:%s: ", ab);
  1406.       perror ("fopen");
  1407.       exit (EXIT_FAILURE);
  1408.     }
  1409.  
  1410.   fprintf (e, "# Permissions file automatically generated by uuconv.\n");
  1411.  
  1412.   for (q = qVperms; q != NULL; q = q->qnext)
  1413.     {
  1414.       size_t ccol;
  1415.  
  1416.       ccol = 0;
  1417.       uvwrite_perm_array (e, (const char **) q->pzlogname, "LOGNAME", &ccol);
  1418.       uvwrite_perm_array (e, (const char **) q->pzmachine, "MACHINE", &ccol);
  1419.       uvwrite_perm_boolean (e, q->frequest, "REQUEST", &ccol, FALSE);
  1420.       uvwrite_perm_boolean (e, q->fsendfiles, "SENDFILES", &ccol, TRUE);
  1421.       uvwrite_perm_rw_array (e, (const char **) q->pzread, "READ", &ccol);
  1422.       uvwrite_perm_rw_array (e, (const char **) q->pzwrite, "WRITE", &ccol);
  1423.       uvwrite_perm_boolean (e, q->fcallback, "CALLBACK", &ccol, FALSE);
  1424.       uvwrite_perm_array (e, (const char **) q->pzcommands, "COMMANDS",
  1425.               &ccol);
  1426.       uvwrite_perm_array (e, (const char **) q->pzvalidate, "VALIDATE",
  1427.               &ccol);
  1428.       uvwrite_perm_string (e, q->zmyname, "MYNAME", &ccol);
  1429.       uvwrite_perm_string (e, q->zpubdir, "PUBDIR", &ccol);
  1430.       uvwrite_perm_array (e, (const char **) q->pzalias, "ALIAS", &ccol);
  1431.  
  1432.       fprintf (e, "\n");
  1433.     }
  1434.  
  1435.   if (ferror (e)
  1436.       || fclose (e) == EOF)
  1437.     {
  1438.       fprintf (stderr, "uuchk:%s: error during output\n", HDB_PERMISSIONS);
  1439.       exit (EXIT_FAILURE);
  1440.     }
  1441. }
  1442.  
  1443. /* Write an array out to the Permissions file.  */
  1444.  
  1445. static void
  1446. uvwrite_perm_array (e, pzarg, zcmd, pccol)
  1447.      FILE *e;
  1448.      const char **pzarg;
  1449.      const char *zcmd;
  1450.      size_t *pccol;
  1451. {
  1452.   size_t c;
  1453.   const char **pz;
  1454.  
  1455.   if (pzarg == NULL)
  1456.     return;
  1457.  
  1458.   c = strlen (zcmd) + 1;
  1459.   
  1460.   for (pz = pzarg; *pz != NULL; pz++)
  1461.     c += strlen (*pz) + 1;
  1462.  
  1463.   if (*pccol > 20 && c + *pccol > 75)
  1464.     {
  1465.       fprintf (e, " \\\n");
  1466.       *pccol = c - 1;
  1467.     }
  1468.   else
  1469.     {
  1470.       if (*pccol != 0)
  1471.     fprintf (e, " ");
  1472.       *pccol += c;
  1473.     }
  1474.  
  1475.   fprintf (e, "%s=", zcmd);
  1476.   for (pz = pzarg; *pz != NULL; pz++)
  1477.     {
  1478.       if (pz != pzarg)
  1479.     fprintf (e, ":");
  1480.       fprintf (e, "%s", *pz);
  1481.     }
  1482. }
  1483.  
  1484. /* Write a boolean value out to the Permissions file.  This may be
  1485.    either a yes/no boolean or a yes/call boolean (the latter is for
  1486.    SENDFILES).  */
  1487.  
  1488. static void
  1489. uvwrite_perm_boolean (e, f, zcmd, pccol, fsendfiles)
  1490.      FILE *e;
  1491.      int f;
  1492.      const char *zcmd;
  1493.      size_t *pccol;
  1494.      boolean fsendfiles;
  1495. {
  1496.   const char *az[2];
  1497.  
  1498.   if (f < 0)
  1499.     return;
  1500.  
  1501.   if (f)
  1502.     az[0] = "yes";
  1503.   else
  1504.     az[0] = fsendfiles ? "call" : "no";
  1505.   az[1] = NULL;
  1506.  
  1507.   uvwrite_perm_array (e, az, zcmd, pccol);
  1508. }
  1509.  
  1510. /* Write a set of READ or WRITE entries to the Permissions file.  We
  1511.    have to separate out all entries that start with '!'.  */
  1512.  
  1513. static void
  1514. uvwrite_perm_rw_array (e, pzarg, zcmd, pccol)
  1515.      FILE *e;
  1516.      const char **pzarg;
  1517.      const char *zcmd;
  1518.      size_t *pccol;
  1519. {
  1520.   size_t c;
  1521.   const char **pz, **pzcopy, **pzset;
  1522.  
  1523.   if (pzarg == NULL)
  1524.     return;
  1525.  
  1526.   c = 0;
  1527.   for (pz = pzarg; *pz != NULL; pz++)
  1528.     c++;
  1529.  
  1530.   pzcopy = (const char **) malloc ((c + 1) * sizeof (char *));
  1531.   if (pzcopy == NULL)
  1532.     uvuuconf_error ((pointer) NULL, UUCONF_MALLOC_FAILED);
  1533.  
  1534.   pzset = pzcopy;
  1535.   for (pz = pzarg; *pz != NULL; pz++)
  1536.     if ((*pz)[0] != '!')
  1537.       *pzset++ = *pz;
  1538.   *pzset = NULL;
  1539.  
  1540.   if (pzset != pzcopy)
  1541.     uvwrite_perm_array (e, (const char **) pzcopy, zcmd, pccol);
  1542.  
  1543.   pzset = pzcopy;
  1544.   for (pz = pzarg; *pz != NULL; pz++)
  1545.     if ((*pz)[0] == '!')
  1546.       *pzset++ = *pz;
  1547.   *pzset = NULL;
  1548.  
  1549.   if (pzset != pzcopy)
  1550.     {
  1551.       char ab[20];
  1552.  
  1553.       sprintf (ab, "NO%s", zcmd);
  1554.       uvwrite_perm_array (e, (const char **) pzcopy, ab, pccol);
  1555.     }
  1556. }
  1557.  
  1558. /* Write a string out to the Permissions file.  */
  1559.  
  1560. static void
  1561. uvwrite_perm_string (e, z, zcmd, pccol)
  1562.      FILE *e;
  1563.      const char *z;
  1564.      const char *zcmd;
  1565.      size_t *pccol;
  1566. {
  1567.   const char *az[2];
  1568.  
  1569.   if (z == NULL)
  1570.     return;
  1571.  
  1572.   az[0] = z;
  1573.   az[1] = NULL;
  1574.  
  1575.   uvwrite_perm_array (e, az, zcmd, pccol);
  1576. }
  1577.  
  1578. /* Write out a Taylor UUCP port.  This is called via uuconf_find_port;
  1579.    the pinfo argument is the port file.  */
  1580.  
  1581. static int
  1582. ivwrite_taylor_port (qport, pinfo)
  1583.      struct uuconf_port *qport;
  1584.      pointer pinfo;
  1585. {
  1586.   FILE *e = (FILE *) pinfo;
  1587.  
  1588.   fprintf (e, "port %s\n", qport->uuconf_zname);
  1589.  
  1590.   uvwrite_taylor_port (e, qport, "");
  1591.  
  1592.   /* Return UUCONF_NOT_FOUND to force uuconf_find_port to keep looking
  1593.      for ports.  */
  1594.   return UUCONF_NOT_FOUND;
  1595. }
  1596.  
  1597. /* Write a port out to a Taylor UUCP configuration file.  This doesn't
  1598.    output the name, since it is called to output a specially defined
  1599.    port in the sys file.  */
  1600.  
  1601. static void
  1602. uvwrite_taylor_port (e, qport, zprefix)
  1603.      FILE *e;
  1604.      struct uuconf_port *qport;
  1605.      const char *zprefix;
  1606. {
  1607.   const char *ztype;
  1608.   char ab[100];
  1609.  
  1610.   switch (qport->uuconf_ttype)
  1611.     {
  1612.     default:
  1613.     case UUCONF_PORTTYPE_UNKNOWN:
  1614.       fprintf (stderr, "uuconv: Bad port type\n");
  1615.       exit (EXIT_FAILURE);
  1616.       break;
  1617.     case UUCONF_PORTTYPE_STDIN:
  1618.       ztype = "stdin";
  1619.       break;
  1620.     case UUCONF_PORTTYPE_MODEM:
  1621.       ztype = "modem";
  1622.       break;
  1623.     case UUCONF_PORTTYPE_DIRECT:
  1624.       ztype = "direct";
  1625.       break;
  1626.     case UUCONF_PORTTYPE_TCP:
  1627.       ztype = "tcp";
  1628.       break;
  1629.     case UUCONF_PORTTYPE_TLI:
  1630.       ztype = "tli";
  1631.       break;
  1632.     }
  1633.  
  1634.   fprintf (e, "%stype %s\n", zprefix, ztype);
  1635.  
  1636.   if (qport->uuconf_zprotocols != NULL)
  1637.     fprintf (e, "%sprotocol %s\n", zprefix, qport->uuconf_zprotocols);
  1638.  
  1639.   if (qport->uuconf_qproto_params != NULL)
  1640.     uvwrite_proto_params (e, qport->uuconf_qproto_params, zprefix);
  1641.  
  1642.   if ((qport->uuconf_ireliable & UUCONF_RELIABLE_SPECIFIED) != 0)
  1643.     {
  1644.       sprintf (ab, "%sseven-bit", zprefix);
  1645.       uvwrite_boolean (e,
  1646.                ((qport->uuconf_ireliable & UUCONF_RELIABLE_EIGHT)
  1647.             == 0),
  1648.                ab);
  1649.       sprintf (ab, "%sreliable", zprefix);
  1650.       uvwrite_boolean (e,
  1651.                ((qport->uuconf_ireliable & UUCONF_RELIABLE_RELIABLE)
  1652.             != 0),
  1653.                ab);
  1654.       sprintf (ab, "%shalf-duplex", zprefix);
  1655.       uvwrite_boolean (e,
  1656.                ((qport->uuconf_ireliable & UUCONF_RELIABLE_FULLDUPLEX)
  1657.             == 0),
  1658.                ab);
  1659.     }
  1660.  
  1661.   if (qport->uuconf_zlockname != NULL)
  1662.     fprintf (e, "%slockname %s\n", zprefix, qport->uuconf_zlockname);
  1663.  
  1664.   switch (qport->uuconf_ttype)
  1665.     {
  1666.     default:
  1667.       break;
  1668.     case UUCONF_PORTTYPE_MODEM:
  1669.       {
  1670.     struct uuconf_modem_port *qm;
  1671.  
  1672.     qm = &qport->uuconf_u.uuconf_smodem;
  1673.     if (qm->uuconf_zdevice != NULL)
  1674.       fprintf (e, "%sdevice %s\n", zprefix, qm->uuconf_zdevice);
  1675.     if (qm->uuconf_zdial_device != NULL)
  1676.       fprintf (e, "%sdial-device %s\n", zprefix, qm->uuconf_zdial_device);
  1677.     if (qm->uuconf_ibaud != 0)
  1678.       fprintf (e, "%sbaud %ld\n", zprefix, qm->uuconf_ibaud);
  1679.     if (qm->uuconf_ilowbaud != 0)
  1680.       fprintf (e, "%sbaud-range %ld %ld\n", zprefix, qm->uuconf_ilowbaud,
  1681.            qm->uuconf_ihighbaud);
  1682.     if (! qm->uuconf_fcarrier)
  1683.       fprintf (e, "%scarrier false\n", zprefix);
  1684.     if (qm->uuconf_pzdialer != NULL)
  1685.       {
  1686.         if (qm->uuconf_pzdialer[1] == NULL)
  1687.           fprintf (e, "%sdialer %s\n", zprefix, qm->uuconf_pzdialer[0]);
  1688.         else
  1689.           {
  1690.         sprintf (ab, "%sdialer-sequence", zprefix);
  1691.         uvwrite_string_array (e, qm->uuconf_pzdialer, zprefix);
  1692.           }
  1693.       }
  1694.     if (qm->uuconf_qdialer != NULL)
  1695.       {
  1696.         sprintf (ab, "%sdialer ", zprefix);
  1697.         uvwrite_taylor_dialer (e, qm->uuconf_qdialer, ab);
  1698.       }
  1699.       }
  1700.       break;
  1701.     case UUCONF_PORTTYPE_DIRECT:
  1702.       {
  1703.     struct uuconf_direct_port *qd;
  1704.  
  1705.     qd = &qport->uuconf_u.uuconf_sdirect;
  1706.     if (qd->uuconf_zdevice != NULL)
  1707.       fprintf (e, "%sdevice %s\n", zprefix, qd->uuconf_zdevice);
  1708.     if (qd->uuconf_ibaud != 0)
  1709.       fprintf (e, "%sbaud %ld\n", zprefix, qd->uuconf_ibaud);
  1710.       }
  1711.       break;
  1712.     case UUCONF_PORTTYPE_TCP:
  1713.       if (qport->uuconf_u.uuconf_stcp.uuconf_zport != NULL)
  1714.     fprintf (e, "%sservice %s\n", zprefix,
  1715.          qport->uuconf_u.uuconf_stcp.uuconf_zport);
  1716.       break;
  1717.     case UUCONF_PORTTYPE_TLI:
  1718.       {
  1719.     struct uuconf_tli_port *qt;
  1720.  
  1721.     qt = &qport->uuconf_u.uuconf_stli;
  1722.     if (qt->uuconf_zdevice != NULL)
  1723.       fprintf (e, "%sdevice %s\n", zprefix, qt->uuconf_zdevice);
  1724.     sprintf (ab, "%sstream", zprefix);
  1725.     uvwrite_boolean (e, qt->uuconf_fstream, ab);
  1726.     if (qt->uuconf_pzpush != NULL)
  1727.       {
  1728.         sprintf (ab, "%spush", zprefix);
  1729.         uvwrite_string_array (e, qt->uuconf_pzpush, ab);
  1730.       }
  1731.     if (qt->uuconf_pzdialer != NULL)
  1732.       {
  1733.         sprintf (ab, "%sdialer-sequence", zprefix);
  1734.         uvwrite_string_array (e, qt->uuconf_pzdialer, ab);
  1735.       }
  1736.     if (qt->uuconf_zservaddr != NULL)
  1737.       fprintf (e, "%sserver-address %s\n", zprefix,
  1738.            qt->uuconf_zservaddr);
  1739.       }
  1740.       break;
  1741.     }
  1742. }
  1743.  
  1744. /* Write out a port to the V2 L-devices file.  This is called via
  1745.    uuconf_find_port.  */
  1746.  
  1747. static int
  1748. ivwrite_v2_port (qport, pinfo)
  1749.      struct uuconf_port *qport;
  1750.      pointer pinfo;
  1751. {
  1752.   FILE *e = (FILE *) pinfo;
  1753.  
  1754.   if (qport->uuconf_ttype == UUCONF_PORTTYPE_DIRECT)
  1755.     {
  1756.       fprintf (e, "DIR %s - %ld direct",
  1757.            qport->uuconf_u.uuconf_sdirect.uuconf_zdevice,
  1758.            qport->uuconf_u.uuconf_sdirect.uuconf_ibaud);
  1759.     }
  1760.   else if (qport->uuconf_ttype == UUCONF_PORTTYPE_MODEM)
  1761.     {
  1762.       fprintf (e, "%s %s ", qport->uuconf_zname,
  1763.            qport->uuconf_u.uuconf_smodem.uuconf_zdevice);
  1764.       if (qport->uuconf_u.uuconf_smodem.uuconf_zdial_device != NULL)
  1765.     fprintf (e, "%s", qport->uuconf_u.uuconf_smodem.uuconf_zdial_device);
  1766.       else
  1767.     fprintf (e, "-");
  1768.       fprintf (e, " ");
  1769.       if (qport->uuconf_u.uuconf_smodem.uuconf_ilowbaud != 0L)
  1770.     fprintf (e, "%ld-%ld",
  1771.          qport->uuconf_u.uuconf_smodem.uuconf_ilowbaud,
  1772.          qport->uuconf_u.uuconf_smodem.uuconf_ihighbaud);
  1773.       else if (qport->uuconf_u.uuconf_smodem.uuconf_ibaud != 0L)
  1774.     fprintf (e, "%ld", qport->uuconf_u.uuconf_smodem.uuconf_ibaud);
  1775.       else
  1776.     fprintf (e, "Any");
  1777.       if (qport->uuconf_u.uuconf_smodem.uuconf_pzdialer != NULL)
  1778.     fprintf (e, " %s",
  1779.          qport->uuconf_u.uuconf_smodem.uuconf_pzdialer[0]);
  1780.     }
  1781.   else
  1782.     {
  1783.       fprintf (e, "# Ignoring port %s with unsupported type",
  1784.            qport->uuconf_zname);
  1785.     }
  1786.  
  1787.   fprintf (e, "\n");
  1788.  
  1789.   /* Return UUCONF_NOT_FOUND to force uuconf_find_port to keep looking
  1790.      for a port.  */
  1791.   return UUCONF_NOT_FOUND;
  1792. }
  1793.  
  1794. /* Write out a port to the HDB Devices file.  This is called via
  1795.    uuconf_find_port.  */
  1796.  
  1797. static int
  1798. ivwrite_hdb_port (qport, pinfo)
  1799.      struct uuconf_port *qport;
  1800.      pointer pinfo;
  1801. {
  1802.   FILE *e = (FILE *) pinfo;
  1803.  
  1804.   if (qport->uuconf_ttype == UUCONF_PORTTYPE_DIRECT)
  1805.     {
  1806.       fprintf (e, "Direct");
  1807.       if (qport->uuconf_zprotocols != NULL)
  1808.     fprintf (e, ",%s", qport->uuconf_zprotocols);
  1809.       fprintf (e, " ");
  1810.       if (qport->uuconf_u.uuconf_sdirect.uuconf_zdevice != NULL)
  1811.     fprintf (e, "%s", qport->uuconf_u.uuconf_sdirect.uuconf_zdevice);
  1812.       else
  1813.     fprintf (e, "%s", qport->uuconf_zname);
  1814.       fprintf (e, " - %ld", qport->uuconf_u.uuconf_sdirect.uuconf_ibaud);
  1815.     }
  1816.   else if (qport->uuconf_ttype == UUCONF_PORTTYPE_MODEM)
  1817.     {
  1818.       fprintf (e, "%s", qport->uuconf_zname);
  1819.       if (qport->uuconf_zprotocols != NULL)
  1820.     fprintf (e, ",%s", qport->uuconf_zprotocols);
  1821.       fprintf (e, " ");
  1822.       if (qport->uuconf_u.uuconf_smodem.uuconf_zdevice != NULL)
  1823.     fprintf (e, "%s", qport->uuconf_u.uuconf_smodem.uuconf_zdevice);
  1824.       else
  1825.     fprintf (e, "%s", qport->uuconf_zname);
  1826.       fprintf (e, " ");
  1827.       if (qport->uuconf_u.uuconf_smodem.uuconf_zdial_device != NULL)
  1828.     fprintf (e, "%s", qport->uuconf_u.uuconf_smodem.uuconf_zdial_device);
  1829.       else
  1830.     fprintf (e, "-");
  1831.       fprintf (e, " ");
  1832.       if (qport->uuconf_u.uuconf_smodem.uuconf_ilowbaud != 0L)
  1833.     fprintf (e, "%ld-%ld",
  1834.          qport->uuconf_u.uuconf_smodem.uuconf_ilowbaud,
  1835.          qport->uuconf_u.uuconf_smodem.uuconf_ihighbaud);
  1836.       else if (qport->uuconf_u.uuconf_smodem.uuconf_ibaud != 0L)
  1837.     fprintf (e, "%ld", qport->uuconf_u.uuconf_smodem.uuconf_ibaud);
  1838.       else
  1839.     fprintf (e, "Any");
  1840.       if (qport->uuconf_u.uuconf_smodem.uuconf_pzdialer != NULL)
  1841.     {
  1842.       char **pz;
  1843.  
  1844.       for (pz = qport->uuconf_u.uuconf_smodem.uuconf_pzdialer;
  1845.            *pz != NULL;
  1846.            pz++)
  1847.         fprintf (e, " %s", *pz);
  1848.     }
  1849.     }
  1850.   else if (qport->uuconf_ttype == UUCONF_PORTTYPE_TCP)
  1851.     {
  1852.       fprintf (e, "TCP");
  1853.       if (qport->uuconf_zprotocols != NULL)
  1854.     fprintf (e, ",%s", qport->uuconf_zprotocols);
  1855.       fprintf (e, " ");
  1856.       if (qport->uuconf_u.uuconf_stcp.uuconf_zport == NULL)
  1857.     fprintf (e, "uucp");
  1858.       else
  1859.     fprintf (e, "%s", qport->uuconf_u.uuconf_stcp.uuconf_zport);
  1860.       fprintf (e, " - -");
  1861.     }
  1862.   else if (qport->uuconf_ttype == UUCONF_PORTTYPE_TLI)
  1863.     {
  1864.       char **pz;
  1865.  
  1866.       fprintf (e, "%s", qport->uuconf_zname);
  1867.       if (qport->uuconf_zprotocols != NULL)
  1868.     fprintf (e, ",%s", qport->uuconf_zprotocols);
  1869.       fprintf (e, " ");
  1870.       if (qport->uuconf_u.uuconf_stli.uuconf_zdevice != NULL)
  1871.     fprintf (e, "%s", qport->uuconf_u.uuconf_smodem.uuconf_zdevice);
  1872.       else
  1873.     fprintf (e, "-");
  1874.       fprintf (e, " - -");
  1875.       pz = qport->uuconf_u.uuconf_stli.uuconf_pzdialer;
  1876.       if (pz == NULL
  1877.       || *pz == NULL
  1878.       || (strcmp (*pz, "TLI") != 0
  1879.           && strcmp (*pz, "TLIS") != 0))
  1880.     fprintf (e, " TLI%s \\D",
  1881.          qport->uuconf_u.uuconf_stli.uuconf_fstream ? "S" : "");
  1882.       if (pz != NULL)
  1883.     for (; *pz != NULL; pz++)
  1884.       fprintf (e, " %s", *pz);
  1885.     }
  1886.   else
  1887.     {
  1888.       fprintf (e, "# Ignoring port %s with unsupported type",
  1889.            qport->uuconf_zname);
  1890.     }
  1891.  
  1892.   fprintf (e, "\n");
  1893.  
  1894.   /* Return UUCONF_NOT_FOUND to force uuconf_find_port to keep looking
  1895.      for a port.  */
  1896.   return UUCONF_NOT_FOUND;
  1897. }
  1898.  
  1899. /* Write a dialer out to a Taylor UUCP configuration file.  This
  1900.    doesn't output the name, since it is called to output a specially
  1901.    defined dialer in the sys or port file.  */
  1902.  
  1903. static void
  1904. uvwrite_taylor_dialer (e, qdialer, zprefix)
  1905.      FILE *e;
  1906.      struct uuconf_dialer *qdialer;
  1907.      const char *zprefix;
  1908. {
  1909.   char ab[100];
  1910.  
  1911.   /* Reset default values, so we don't output them unnecessarily.  */
  1912.   if (qdialer->uuconf_schat.uuconf_ctimeout == 60)
  1913.     qdialer->uuconf_schat.uuconf_ctimeout = -1;
  1914.   if (qdialer->uuconf_schat.uuconf_fstrip)
  1915.     qdialer->uuconf_schat.uuconf_fstrip = -1;
  1916.   if (qdialer->uuconf_scomplete.uuconf_ctimeout == 60)
  1917.     qdialer->uuconf_scomplete.uuconf_ctimeout = -1;
  1918.   if (qdialer->uuconf_scomplete.uuconf_fstrip)
  1919.     qdialer->uuconf_scomplete.uuconf_fstrip = -1;
  1920.   if (qdialer->uuconf_sabort.uuconf_ctimeout == 60)
  1921.     qdialer->uuconf_sabort.uuconf_ctimeout = -1;
  1922.   if (qdialer->uuconf_sabort.uuconf_fstrip)
  1923.     qdialer->uuconf_sabort.uuconf_fstrip = -1;
  1924.   
  1925.   uvwrite_chat (e, &qdialer->uuconf_schat, (struct uuconf_chat *) NULL,
  1926.         zprefix, FALSE);
  1927.   if (qdialer->uuconf_zdialtone != NULL
  1928.       && strcmp (qdialer->uuconf_zdialtone, ",") != 0)
  1929.     fprintf (e, "%sdialtone %s\n", zprefix, qdialer->uuconf_zdialtone);
  1930.   if (qdialer->uuconf_zpause != NULL
  1931.       && strcmp (qdialer->uuconf_zpause, ",") != 0)
  1932.     fprintf (e, "%spause %s\n", zprefix, qdialer->uuconf_zpause);
  1933.   if (! qdialer->uuconf_fcarrier)
  1934.     fprintf (e, "%scarrier false\n", zprefix);
  1935.   if (qdialer->uuconf_ccarrier_wait != 60)
  1936.     fprintf (e, "%scarrier-wait %d\n", zprefix,
  1937.          qdialer->uuconf_ccarrier_wait);
  1938.   if (qdialer->uuconf_fdtr_toggle)
  1939.     fprintf (e, "%sdtr-toggle %s %s\n", zprefix,
  1940.          qdialer->uuconf_fdtr_toggle ? "true" : "false",
  1941.          qdialer->uuconf_fdtr_toggle_wait ? "true" : "false");
  1942.   sprintf (ab, "%scomplete-", zprefix);
  1943.   uvwrite_chat (e, &qdialer->uuconf_scomplete, (struct uuconf_chat *) NULL,
  1944.         ab, FALSE);
  1945.   sprintf (ab, "%sabort-", zprefix);
  1946.   uvwrite_chat (e, &qdialer->uuconf_sabort, (struct uuconf_chat *) NULL,
  1947.         ab, FALSE);
  1948.   if (qdialer->uuconf_qproto_params != NULL)
  1949.     uvwrite_proto_params (e, qdialer->uuconf_qproto_params, zprefix);
  1950.   if ((qdialer->uuconf_ireliable & UUCONF_RELIABLE_SPECIFIED) != 0)
  1951.     {
  1952.       sprintf (ab, "%sseven-bit", zprefix);
  1953.       uvwrite_boolean (e,
  1954.                ((qdialer->uuconf_ireliable & UUCONF_RELIABLE_EIGHT)
  1955.             == 0),
  1956.                ab);
  1957.       sprintf (ab, "%sreliable", zprefix);
  1958.       uvwrite_boolean (e,
  1959.                ((qdialer->uuconf_ireliable & UUCONF_RELIABLE_RELIABLE)
  1960.             != 0),
  1961.                ab);
  1962.       sprintf (ab, "%shalf-duplex", zprefix);
  1963.       uvwrite_boolean (e,
  1964.                ((qdialer->uuconf_ireliable
  1965.              & UUCONF_RELIABLE_FULLDUPLEX) == 0),
  1966.                ab);
  1967.     }
  1968. }
  1969.  
  1970. /* Write a dialer out to an HDB configuration file.  */
  1971.  
  1972. static void
  1973. uvwrite_hdb_dialer (e, qdialer)
  1974.      FILE *e;
  1975.      struct uuconf_dialer *qdialer;
  1976. {
  1977.   fprintf (e, "%s ", qdialer->uuconf_zname);
  1978.  
  1979.   if (qdialer->uuconf_zdialtone != NULL)
  1980.     fprintf (e, "=%c", qdialer->uuconf_zdialtone[0]);
  1981.   if (qdialer->uuconf_zpause != NULL)
  1982.     fprintf (e, "-%c", qdialer->uuconf_zpause[0]);
  1983.  
  1984.   if (qdialer->uuconf_schat.uuconf_pzchat != NULL)
  1985.     {
  1986.       if (qdialer->uuconf_zdialtone == NULL
  1987.       && qdialer->uuconf_zpause == NULL)
  1988.     fprintf (e, "\"\"");
  1989.       fprintf (e, " ");
  1990.       uvwrite_chat_script (e, qdialer->uuconf_schat.uuconf_pzchat);
  1991.     }
  1992.  
  1993.   fprintf (e, "\n");
  1994. }
  1995.  
  1996. /* Display a uuconf error and exit.  */
  1997.  
  1998. static void
  1999. uvuuconf_error (puuconf, iret)
  2000.      pointer puuconf;
  2001.      int iret;
  2002. {
  2003.   char ab[512];
  2004.  
  2005.   (void) uuconf_error_string (puuconf, iret, ab, sizeof ab);
  2006.   if ((iret & UUCONF_ERROR_FILENAME) == 0)
  2007.     fprintf (stderr, "uuconv: %s\n", ab);
  2008.   else
  2009.     fprintf (stderr, "uuconv:%s\n", ab);
  2010.   if (UUCONF_ERROR_VALUE (iret) != UUCONF_FOPEN_FAILED)
  2011.     exit (EXIT_FAILURE);
  2012. }
  2013.